package com.hcj.shiro;

import com.hcj.admin.entity.TPermission;
import com.hcj.admin.entity.TRole;
import com.hcj.admin.entity.TUser;
import com.hcj.admin.service.ITPermissionService;
import com.hcj.admin.service.ITUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author: HuangChangjin 2017-10-23 18:14
 * @Description:
 */
public class ShiroRealm extends AuthorizingRealm {
    private static  final  Logger logger =  LoggerFactory.getLogger(ShiroRealm.class);

    @Autowired
    private ITUserService userService;
    @Autowired
    private ITPermissionService permissionService;

    /**
     * 授权认证
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.error("\n授权doGetAuthorizationInfo+"+principalCollection.toString());
        TUser user = userService.getByUserName((String) principalCollection.getPrimaryPrincipal());


        //把principals放session中 key=userId value=principals
        SecurityUtils.getSubject().getSession().setAttribute(String.valueOf(user.getId()),SecurityUtils.getSubject().getPrincipals());

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //赋予角色
        for(TRole userRole:user.getRoles()){
            info.addRole(userRole.getName());
        }
        //赋予权限
        for(TPermission permission:permissionService.getByUserId(user.getId())){
            //if(StringUtils.isNotBlank(permission.getPermCode()))
            info.addStringPermission(permission.getName());
        }

        //设置登录次数、时间
//        userService.updateUserLogin(user);
        return info;
    }

    /**
     * 登录认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("\n登录认证doGetAuthenticationInfo={}", authenticationToken.toString());

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String userName = token.getUsername();
        logger.error("\n userName=====>"+userName);
        logger.error("\n password=====>"+new String(token.getPassword()));
        TUser user = userService.getByUserName(token.getUsername());
        if (user == null){
            throw  new UnknownAccountException();
        }
        // 判断帐号是否锁定
        if (user.getState() == 1) {
            // 抛出 帐号锁定异常
            throw new LockedAccountException();
        }
        //设置用户session
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("user", user);

        //byte[] salt = Encodes.decodeHex(user.getSalt());
        //ShiroUser shiroUser = new ShiroUser(user.getId(), user.getLoginName(), user.getName());

        String algorithmName = "md5";
        String salt1 = user.getUserName();
        //String salt2 = new SecureRandomNumberGenerator().nextBytes().toHex();
        String salt2 = user.getSalt();
        int hashIterations = 2;
        SimpleHash hash = new SimpleHash(algorithmName, token.getPassword(),salt1 + salt2, hashIterations);
        // 加密过的密码
        String encodedPassword = hash.toHex();
        logger.info("加密过的密码=========={}",encodedPassword);
        // ByteSource.Util.bytes(salt1 + salt2)
        return new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), ByteSource.Util.bytes(salt1 + salt2),getName());
    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }

    public static void main(String[] args) {
        String algorithmName = "md5"; // 加密类型
        String username = "hcj"; // 账号
        String password = "1";// 明文
        String salt1 = username;
        String salt2 = new SecureRandomNumberGenerator().nextBytes().toHex();
        int hashIterations = 2;
        SimpleHash hash = new SimpleHash(algorithmName, password,
                salt1 + salt2, hashIterations);
        String encodedPassword = hash.toHex();
        System.out.println("密文="+encodedPassword);
        System.out.println("冗余盐="+salt2);
    }

}
